package com.oracle.application.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.oracle.application.entity.Orderitems;
import com.oracle.application.entity.Orders;
import com.oracle.application.entity.vo.*;
import com.oracle.application.mapper.OrderitemsMapper;
import com.oracle.application.mapper.OrdersMapper;
import com.oracle.application.service.IOrdersService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import redis.clients.jedis.JedisCluster;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 *
 */
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements IOrdersService {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired(required = false)
    private OrderitemsMapper orderitemsMapper;
    @Autowired(required = false)
    private  OrdersMapper ordersMapper;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    public DirectExchange orderDirectExchange;
    @Override
    public OrderConfirmVo createorderConfirm() {
        String orderTokenValue=UUID.randomUUID().toString().replaceAll("-","");
        AddreseVo addreseVo=new AddreseVo();
        addreseVo.setAddress("河南省开封市");
        addreseVo.setConsignee("张三");
        addreseVo.setArea("河南");
        addreseVo.setPhone("111111111");
        addreseVo.setIsDefault(false);

        AddreseVo addreseVo1=new AddreseVo();
        addreseVo1.setAddress("河南省开封市");
        addreseVo1.setConsignee("李四");
        addreseVo1.setArea("河南");
        addreseVo1.setPhone("22222222");
        addreseVo.setIsDefault(false);

        AddreseVo addreseVo2=new AddreseVo();
        addreseVo2.setAddress("河南省开封市");
        addreseVo2.setConsignee("王五");
        addreseVo2.setArea("河南");
        addreseVo2.setPhone("3333333");
        addreseVo.setIsDefault(false);
        List<AddreseVo> addreseVoList=new ArrayList<>();
        addreseVoList.add(addreseVo);
        addreseVoList.add(addreseVo1);
        addreseVoList.add(addreseVo2);

        OrderitemsVo orderitemsVo=new OrderitemsVo();
        orderitemsVo.setImage("sdfghjghgfd");
        orderitemsVo.setNum(1);
        orderitemsVo.setPrice(new BigDecimal(100));
        orderitemsVo.setSkuname("水杯");
        orderitemsVo.setSkusn("1567865513");

        OrderitemsVo orderitemsVo1=new OrderitemsVo();
        orderitemsVo1.setImage("sdfghjghgfd");
        orderitemsVo1.setNum(1);
        orderitemsVo1.setPrice(new BigDecimal(200));
        orderitemsVo1.setSkuname("电脑");
        orderitemsVo1.setSkusn("1567865513");

        OrderitemsVo orderitemsVo2=new OrderitemsVo();
        orderitemsVo2.setImage("sdfghjghgfd");
        orderitemsVo2.setNum(1);
        orderitemsVo2.setPrice(new BigDecimal(100));
        orderitemsVo2.setSkuname("玩具");
        orderitemsVo2.setSkusn("1567865513");

        List<OrderitemsVo> orderitemsVoList=new ArrayList<>();
        orderitemsVoList.add(orderitemsVo);
        orderitemsVoList.add(orderitemsVo1);
        orderitemsVoList.add(orderitemsVo2);
        BigDecimal totalPrice=new BigDecimal("0.0");
        for (OrderitemsVo vo:orderitemsVoList){
            totalPrice=totalPrice.add(vo.getPrice().multiply(new BigDecimal(vo.getNum())));
        }
        final  String orderTokenKey="pay:ordertoken:"+1;
        this.redisTemplate.boundValueOps(orderTokenKey).set(orderTokenValue);
        String payMethod="在线支付-支付宝支付";
        OrderConfirmVo orderConfirmVo=new OrderConfirmVo();
        orderConfirmVo.setAddreseVoList(addreseVoList);
        orderConfirmVo.setOrderToken(orderTokenValue);
        orderConfirmVo.setPayMethod(payMethod);
        orderConfirmVo.setTotalPrice(totalPrice.setScale(2,BigDecimal.ROUND_DOWN));
        orderConfirmVo.setOrderitemsVoList(orderitemsVoList);
        return orderConfirmVo;
    }

    @Override
    public Map<String,Object> submitOrder(OrderSubmitVo orderSubmitVo) {
        Map<String,Object> rMap=new HashMap<>();
        final  String orderTokenKey="pay:ordertoken:"+1;
        //下面是正确的删除
        String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";
        //lua脚本方式释放锁
        Long result=this.redisTemplate.execute(new RedisCallback<Long>() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                Object nativeConnection = connection.getNativeConnection();

                // 集群模式
                if (nativeConnection instanceof JedisCluster) {
                    return (Long) ((JedisCluster) nativeConnection).eval(script, Arrays.asList(orderTokenKey), Arrays.asList(orderSubmitVo.getOrderToken()));
                }
                return null;
            }
        });
        if (result==null||result==0){
            rMap.put("code",500);
            return  rMap;
        }
        try {
            Orders orders=new Orders();
            orders.setArea(orderSubmitVo.getAddreseVo().getArea());
            orders.setPhone(orderSubmitVo.getAddreseVo().getPhone());
            orders.setZipcode("475200");
            orders.setPaystatus(0);
            orders.setOrderstatus(0);
            orders.setMember(1);
            orders.setConsignee(orderSubmitVo.getAddreseVo().getConsignee());
            orders.setCreatedate(LocalDateTime.now());
            orders.setModifydate(LocalDateTime.now());
            orders.setExpiredate(orders.getCreatedate().plusMinutes(30));
            orders.setAddress(orderSubmitVo.getAddreseVo().getAddress());
            orders.setPaymethod(orderSubmitVo.getPayMethod());
            List<Orderitems>orderitemsList=orderSubmitVo.getOrderitemsVoList().stream().map(orderitemsVo -> {
                Orderitems orderitems=new Orderitems();
                BeanUtils.copyProperties(orderitemsVo,orderitems);
                return  orderitems;
            }).collect(Collectors.toList());
            BigDecimal totalPrice=new BigDecimal("0.0");
            for (Orderitems orderitems:orderitemsList){
                totalPrice=totalPrice.add(orderitems.getPrice().multiply(new BigDecimal(orderitems.getNum())));
            }
            orders.setTotalprice(totalPrice);
            orders.setOrdersn(IdWorker.getTimeId());
            this.ordersMapper.insert(orders);
            for (Orderitems orderitems:orderitemsList){
                orderitems.setOrders(orders.getId());
                this.orderitemsMapper.insert(orderitems);
            }
            OrdersVo ordersVo=new OrdersVo();
            BeanUtils.copyProperties(orders,ordersVo);
            this.amqpTemplate.convertAndSend(this.orderDirectExchange.getName(),"order.create",JSONObject.toJSONString(ordersVo));

            rMap.put("data",ordersVo);
        } catch (BeansException e) {
            e.printStackTrace();
        }
        return rMap;
    }

    @Override
    public int updateOrderStatus(String orderSn) {
        int i= this.ordersMapper.updateOrderStatus(orderSn);
        return i;
    }
}
